
package org.swim.sessions;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;

import javax.ejb.Stateless;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.persistence.*;
//import org.swim.entity.FakeNotificabile;
import org.swim.entity.*;
import org.swim.entity.Utente.Tipo;

/**
 * Session Bean implementation class GestoreUtenti
 */
@Stateless
public class GestoreUtenti implements GestoreUtentiRemote {

    /**
     * Default constructor. 
     */
    public GestoreUtenti() {
        // TODO Auto-generated constructor stub
    }
    
    @PersistenceContext(unitName = "JPADB")
    private EntityManager um;

	@Override
	public Utente autentica(String idUtente, String password) throws Exception {

		
		return (Utente)um.createNamedQuery("Utente.autentica")
									.setParameter("email",idUtente)
									.setParameter("password",password)
									.getSingleResult();
	}
	
	@Override
	public Utente getUtente(String idUtente) throws Exception {
		// TODO Auto-generated method stub
		
		return (Utente)um.createNamedQuery("Utente.getUtenteByEmail")
									.setParameter("email",idUtente)
									.getSingleResult();
	}
	
	@Override
	public ArrayList<Notificabile> getNotifiche(String idUtente) {
		
		Utente ut = (Utente)um.createNamedQuery("Utente.getUtenteByEmail")
					.setParameter("email",idUtente)
					.getSingleResult();
		
		String query = "SELECT a.* FROM amicizia a "
				+" WHERE (a.emailMit = '"+ idUtente +"' AND a.status = 2) "
				+" OR (a.emailDest = '"+ idUtente +"' AND a.status = 0)";
		
		List<Amicizia> listAmicizia = um.createNativeQuery(query, Amicizia.class).getResultList();
		
		query = "SELECT r.* FROM richiesta_aiuto r "
				+" WHERE (r.emailMit = '"+ idUtente +"' AND r.status <> 0)"
				+" OR (r.emailDest = '"+ idUtente +"' AND r.status = 0)";
		
		List<RichiestaAiuto> listaRichiesta = um.createNativeQuery(query, RichiestaAiuto.class).getResultList();
		
		List<PropostaAbilita> listaProposta = new ArrayList<PropostaAbilita>();
		if(ut.getTipo() == Tipo.AMMINISTRATORE){
			query = "SELECT DISTINCT p.* FROM proposta_abilita p, utente_proposta up "
					+" WHERE (up.emailUtente = '"+ idUtente +"' AND up.nomeAbilita = p.nomeAbilita) "
					+" OR p.status = 0";
			
			listaProposta = um.createNativeQuery(query, PropostaAbilita.class).getResultList();
		}
		else
		{
			query = "SELECT p.* FROM proposta_abilita p, utente_proposta up "
					+" WHERE up.emailUtente = '"+ idUtente +"' AND up.nomeAbilita = p.nomeAbilita AND p.status <> 0";
			
			listaProposta = um.createNativeQuery(query, PropostaAbilita.class).getResultList();
		}
		
		query = "SELECT f.* FROM feedback f, richiesta_aiuto r "
				+" WHERE r.emailDest = '"+ idUtente +"' AND f.id = r.id";
		
		List<Feedback> listaFeedback = um.createNativeQuery(query, Feedback.class).getResultList();
		
		ArrayList<Notificabile> l = new ArrayList<Notificabile>();
		
		l.addAll(listAmicizia);
		l.addAll(listaRichiesta);
		l.addAll(listaProposta);
		l.addAll(listaFeedback);
		
		Collections.sort(l, new Comparator<Notificabile>() {
		    public int compare(Notificabile a, Notificabile b) {
		    	if(a.getDataModifica().after(b.getDataModifica()))
		    		return -1;
		    	if(a.getDataModifica().equals(b.getDataModifica()))
		    		return 0;
		    	if(a.getDataModifica().before(b.getDataModifica()))
		    		return 1;
		        return -2;
		    }
		});
		return l;
	}

	@Override
	public Utente addUtente(Hashtable<String, Object> credenziali) {
		
		Utente u =new Utente();
		u.setEmail((String)credenziali.get("email"));
		u.setPassword((String)credenziali.get("password"));
		u.setNome((String)credenziali.get("nome"));
		u.setCognome((String)credenziali.get("cognome"));
		u.setDataNascita((Date)credenziali.get("dataNascita"));
		u.setCitta((String)credenziali.get("citta"));
		u.setTipo(Tipo.NORMALE);
		um.persist(u);
		return u;

	}

	@Override
	public Amicizia addAmicizia(String idUtenteMit, String idUtenteDest) throws Exception{
		Amicizia a = new Amicizia();
		if(idUtenteMit.equals(idUtenteDest)){
			throw new Exception("Amicizia non riflessiva");
		}
		Utente mittente = (Utente)um.createNamedQuery("Utente.getUtenteByEmail")
						.setParameter("email", idUtenteMit)			
						.getSingleResult();
		Utente destinatario = (Utente)um.createNamedQuery("Utente.getUtenteByEmail")
						.setParameter("email", idUtenteDest)			
						.getSingleResult();
		
		a.setMittente(mittente);
		a.setDestinatario(destinatario);
		a.setDataModifica(new Date(System.currentTimeMillis()));
		a.setStatus(Status.INATTESA);
		um.persist(a);
		return a;

	}

	@Override
	public void removeAmicizia(String idUtente1, String idUtente2) {
		
		String query="DELETE FROM amicizia "
					+" WHERE (emailMit = '"+ idUtente1 +"' AND emailDest = '"+ idUtente2 +"') "
					+" OR (emailDest = '"+ idUtente1 +"' AND emailMit ='"+ idUtente2 +"')";
		 um.createNativeQuery(query, Amicizia.class).executeUpdate();
		 
	}
	
	@Override
	public void valutaAmicizia(String idUtente1, String idUtente2, Status s) {
		String query="SELECT a.* FROM amicizia a "
				+" WHERE (emailMit = '"+ idUtente1 +"' AND emailDest = '"+ idUtente2 +"') "
				+" OR (emailDest = '"+ idUtente1 +"' AND emailMit ='"+ idUtente2 +"')";
		Amicizia a = (Amicizia)um.createNativeQuery(query, Amicizia.class).getSingleResult();
		if (s==Status.ACCETTATA){
			a.setStatus(s);
			um.merge(a);
		}
		else if(s==Status.RIFIUTATA)
			{
				removeAmicizia(idUtente1, idUtente2);
			}
		{
			
		}
	}
	
	@Override
	public void valutaAmiciziaById(int id, Status s) {
		Amicizia a = (Amicizia)um.createNamedQuery("Amcizia.getAmiciziaById")
				.setParameter("id",id)
				.getSingleResult();	
		if (s==Status.ACCETTATA){
			a.setStatus(s);
			um.merge(a);
		}
		else if(s==Status.RIFIUTATA)
			{
				removeAmicizia(a.getMittente().getEmail(), a.getDestinatario().getEmail());
			}
		{
			
		}
	}

	@Override
	public Abilita addAbilita(String idUtente, String nomeAbilita) {
		
		Utente u = (Utente)um.createNamedQuery("Utente.getUtenteByEmail")
				.setParameter("email",idUtente)
				.getSingleResult();
		Abilita ab = (Abilita)um.createNamedQuery("Abilita.getAbilitaByName")
				.setParameter("nome", nomeAbilita)	
				.getSingleResult();
		u.addAbilitaPerUtente(ab);
		um.merge(u);
		
		return ab;
	}

	@Override
	public void removeAbilita(String idUtente, String nomeAbilita) {
		
		String query="DELETE FROM utente_abilita "
				+" WHERE emailUtente = '"+ idUtente +"' AND abilita = '"+ nomeAbilita +"'";
		um.createNativeQuery(query, Abilita.class).executeUpdate();
	}

	@Override
	public List<Abilita> getListAbilita(String idUtente) {
		
		String query = "SELECT a.* FROM abilita a, utente_abilita ua "
					+" WHERE a.nome = ua.abilita AND ua.emailUtente ='"+ idUtente +"'";
		List<Abilita> list = um.createNativeQuery(query, Abilita.class).getResultList();
		return list;
	}

	@Override
	public void changePassword(String idUtente, String newPassword) {

		Utente u = (Utente)um.createNamedQuery("Utente.getUtenteByEmail")
				.setParameter("email",idUtente)
				.getSingleResult();
		u.setPassword(newPassword);
		um.merge(u);
		
	}

	@Override
	public void changeDati(String idUtente, Hashtable<String, Object> dati) {
		
		Utente u = (Utente)um.createNamedQuery("Utente.getUtenteByEmail")
				.setParameter("email",idUtente)
				.getSingleResult();
		
		if(dati.containsKey("nome"))
			u.setNome((String)dati.get("nome"));
		if(dati.containsKey("cognome"))
			u.setCognome((String)dati.get("cognome"));
		if(dati.containsKey("dataNascita"))
			u.setDataNascita((Date)dati.get("dataNascita"));
		if(dati.containsKey("password"))
			u.setPassword((String)dati.get("password"));
		if(dati.containsKey("citta"))
			u.setCitta((String)dati.get("citta"));
		
		um.merge(u);
	}

	@Override
	public Utente addAmministatore() {
		//TODO
		Utente u =new Utente();
		u.setEmail("admin@swim.org");
		u.setPassword("admin");
		u.setNome("Pino");
		u.setCognome("Privilegio");
		u.setDataNascita(new Date(70, 1, 1));
		u.setCitta("Agrigento");
		u.setTipo(Tipo.AMMINISTRATORE);
		um.persist(u);
		
		return u;
	}

	@Override
	public List<Utente> getAmici(String idUtente) {
		String query = "SELECT u.* FROM utente u, amicizia a "
				+" WHERE (a.emailMit = '"+ idUtente +"' AND a.emailDest = u.email) "
				+" OR (a.emailDest = '"+ idUtente +"' AND a.emailMit = u.email)"
				+" AND a.status = 2";
		List<Utente> list = um.createNativeQuery(query, Utente.class).getResultList();
		return list;
	}

	@Override
	public List<Feedback> getFeedbacks(String idUtente) {
		String query = "SELECT f.* FROM feedback f, richiesta_aiuto r "
				+" WHERE f.id = r.id AND r.emailDest = '"+ idUtente +"'";
		List<Feedback> list = um.createNativeQuery(query, Feedback.class).getResultList();
		return list;
	}


	

}
